home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Experimental BBS Explossion 3
/
Experimental BBS Explossion III.iso
/
graphics
/
scrfe100.zip
/
FONTOOLS.PAS
< prev
next >
Wrap
Pascal/Delphi Source File
|
1993-02-27
|
8KB
|
294 lines
UNIT Fontools;
{$F+,O+,D+,R-,S-,V+,E-,N-}
{This Turbo Pascal unit is (C) Copyright 1993, Jeremy Lilley. The author
(Jeremy Lilley) is not responsible for any problems with this unit or
Screen Font Editor and modifying this file may have unpredictable and/or
malevolent results}
interface
CONST
vseg : WORD = $b800; {segment for video activity}
linesperchar : BYTE = 13;
VGA : BOOLEAN = FALSE;
EGA : BOOLEAN = FALSE;{VGA and EGA are set but detEGA at the init.}
TYPE
fontsavetype = array [0..8191] of byte;{for saving the fonts}
{Of the following procedures, you will probably only use readfont
and readscreen. The others are here for advanced programmers to
use. Changing this file MAY HAVE UNPREDICTABLE RESULTS which may
destroy a monitor if improperly done. Do not try to modify thes procedures!
Proper detection is done and though the author makes no warranties,
expressed or implied, there should be no problems when run as is.}
PROCEDURE readfont (bufptr:pointer);
(* Use this to load a font to memory in the form of a disk file or memory
image. Get the .SFF font file, run BINOBJ on it:
Name for pseudo-procedure
\
BINOBJ Fontfile.SFF Fontfile.OBJ Fontdata
You will have an OBJ file, and you must make it into a procedure and
link it like this:
Program Fontdemo;
uses fontools;
{$L Fontfile.OBJ}
procedure Fontdata;EXTERNAL; {Name specified above in BINOBJ}
begin
readfont(@Fontdata);{MUST use "@"}
end.
*)
PROCEDURE readscreen (bufptr:pointer);
(* This procedure is similar to the above except that you use it to load
a screen or part of one. Get the .SFS screen file, run BINOBJ on it:
Name for pseudo-procedure
\
BINOBJ Scrfile.SFF Scrfile.OBJ ScreenData
You will have an OBJ file, and you must make it into a procedure and
link it like this:
Program Scrdemo;
uses fontools;
{$L Scrfile.OBJ}
procedure Screendata;EXTERNAL; {Name specified above in BINOBJ}
begin
readscreen(@Screendata);{MUST use "@"}
end.
*)
procedure resetfonts;
{ This procedure will reset the screen for the default fonts, point size,
and number of scanlines to the system default without clearing the screen.}
procedure savefonts (var buffer:fontsavetype);
{ This procedure saves the currentfonts to a variable of fontsavetype type,
but not point sizes or scan lines}
procedure restorefonts (var buffer:fontsavetype);
{ This procedure retrieves the fonts from a variable of fontsavetype type,
but not the point sizes or scanlines}
PROCEDURE sequencefonts;
{ Sequences controllers so that you can change the fonts by just
moving bit-patterns into segment $A000. Each character occupies
32 bytes, but you will probably not want to use 32-point characters.
To change 1 character "c" if the bit-patterns are at "bit_pat," you
would need to sequence fonts, MOVE(bit_pat,mem[$A000:0],pointsperchar);
and desequence fonts.}
PROCEDURE desequencefonts;{Do this after you are done moving things after
sequence fonts. MAKE SURE TO USE THUS IF YOU USE SEQUENCEFONTS!!!}
PROCEDURE setscanlines (n : BYTE);{ Sets the scanlines on a VGA monitor
where n= 0 : 200 lines, 1 : 350 lines, 2 : 400 lines}
PROCEDURE setlinesperchar;
{sets the number of points per line when linesperchar is equal to the
number of points MINUS 1, i.e. linesperchar=13 makes 14-point characters}
PROCEDURE detEGA ;
{This procedure, called at the beginning of the program, sets the VGA
and EGA variables which allow or disallow various procedures from being
used. It usually need never be called by a programmer.}
implementation
USES dos;
const
fontheader = '@JLSFF' + #1;
type
fontheadertype = STRING [7];
VAR
fontheaderstring : fontheadertype;
PROCEDURE sequencefonts;
BEGIN
if ega then begin
portw [$3c4] := $704;
portw [$3ce] := $204;
portw [$3ce] := 5;
portw [$3ce] := $406;
portw [$3c4] := $402;
end;
END;
PROCEDURE desequencefonts;
BEGIN
if EGA then begin
portw [$3c4] := $302;
portw [$3c4] := $304;
portw [$3ce] := 4;
portw [$3ce] := $1005;
IF vseg = $b800 THEN
portw [$3ce] := $e06 ELSE
portw [$3ce] := $606
end;
END;
PROCEDURE setscanlines (n : BYTE);
VAR
sst : ARRAY [0..3999] OF
CHAR;
r : REGISTERS;
BEGIN
MOVE (mem [vseg : 0], sst, 4000);
IF (n < 3)and(vga) THEN BEGIN
r.ax := $1200 + n;
r.bx := $30;
INTR ($10, r);
r.ax := $83;
IF vseg = $b000 THEN r.ax := $87;
INTR ($10, r);
r.cx := $c0d;
IF n = 0 THEN r.cx := $708;
r.ax := $100;
INTR ($10, r);
end;
MOVE (sst, mem [vseg : 0], 4000);
END;
PROCEDURE setlinesperchar;
VAR
r : REGISTERS;
BEGIN
if ega then begin
r.ax := $1100;
r.bx := (linesperchar * 256);
r.cx := 0;
r.dx := 0;
INTR ($10, r);
end;
END;
PROCEDURE readfont (bufptr:pointer);
VAR
numberofentries : BYTE;
i, j, k : BYTE;
begchar, endchar : BYTE;
segbuf, ofsbuf : WORD;
BEGIN
if EGA then begin
segbuf := SEG (bufptr^);
ofsbuf := OFS (bufptr^);
MOVE(mem[segbuf:ofsbuf],mem[seg(fontheaderstring):ofs(fontheaderstring)+1],7);
mem[seg(fontheaderstring):ofs(fontheaderstring)]:=7;
ofsbuf := ofsbuf + 7;
IF fontheaderstring = fontheader THEN
BEGIN
setscanlines (mem [segbuf : ofsbuf]);
INC (ofsbuf);
linesperchar := mem [segbuf : ofsbuf];
INC (ofsbuf);
setlinesperchar;
IF (linesperchar < 16) THEN
BEGIN
numberofentries := mem [segbuf : ofsbuf];
INC (ofsbuf);
FOR i := 0 TO numberofentries DO
BEGIN
begchar := mem [segbuf : ofsbuf];
INC (ofsbuf);
endchar := mem [segbuf : ofsbuf];
INC (ofsbuf);
FOR j := begchar TO endchar DO
BEGIN
sequencefonts;
MOVE (mem[segbuf:ofsbuf],mem[$a000:32 * j], linesperchar + 1);
desequencefonts;
ofsbuf := ofsbuf + linesperchar + 1;
END;
END;
END;
END;
END;
END;
PROCEDURE readscreen (bufptr:pointer);
VAR
xy,xx : BYTE;
x1, y1, x2, y2 : BYTE;
segbuf, ofsbuf, offset : WORD;
statport : word;
BEGIN
segbuf := SEG (bufptr^);
ofsbuf := OFS (bufptr^);
x1 := mem [segbuf : ofsbuf];
y1 := mem [segbuf : ofsbuf + 1];
x2 := mem [segbuf : ofsbuf + 2];
y2 := mem [segbuf : ofsbuf + 3];
ofsbuf := ofsbuf + 4;
IF x1 > x2 THEN
BEGIN xy := x1;x1 := x2;x2 := xy;END;
IF y1 > y2 THEN BEGIN
xy := y1;y1 := y2;y2 := xy;END;
if vseg=$b800 then statport:=$3d4 else statport:=$3b4;
if ega then FOR xy := y1 TO y2 DO
BEGIN
MOVE (mem [segbuf : ofsbuf], mem [vseg : 2 * ( ( (xy - 1) * 80) + (x1 - 1) ) ], 2 * ( (x2 + 1) - x1) );
ofsbuf := ofsbuf + (2 * ( (x2 + 1) - x1) );
END else for xy:=y1 to y2 do begin
for xx:=x1 to x2 do begin
offset:=(((xy-1)*80)+(xx-1))*2;
repeat until port[statport]<>1;
memw[$b800:offset]:=memw[segbuf:ofsbuf];
inc(ofsbuf,2);end;
end;
END;
PROCEDURE EGA_Grfx (a, b : BYTE);
BEGIN
port [$3ce] := a;
port [$3cf] := b;
END;
PROCEDURE detEGA;
CONST TestMask : BYTE = 1;
VAR Regs : REGISTERS;
BIOSbyte : BYTE;
BEGIN
IF (mem [0 : $410] AND 48) = 48 THEN
vseg := $b000 ELSE
vseg := $b800;
BIOSbyte := mem [ $40 : $87 ];
Regs.AH := $12;
Regs.BL := $10;
Regs.BH := $FF;
INTR ( $10, Regs );
IF (Regs.BL <> (BIOSbyte AND $60) SHR 5) AND
(Regs.BH <> (BIOSbyte AND $02 ) SHR 1 ) AND
( Regs.BH = $FF ) THEN
BEGIN EGA := FALSE; EXIT; END;
EGA_Grfx ( 8, TestMask );
port [ $3CE ] := 8;
IF port [ $3CF ] = TestMask THEN
VGA := TRUE;
EGA_Grfx ( 8, $FF );
EGA := TRUE;
END;
procedure savefonts (var buffer:fontsavetype);
begin
sequencefonts;
move( mem [ $a000 : 0 ], buffer , 8192 );
desequencefonts;
end;
procedure restorefonts (var buffer:fontsavetype);
begin
sequencefonts;
move( buffer , mem [ $a000 : 0 ] , 8192 );
desequencefonts;
end;
procedure resetfonts;
begin
inline( $b8 / $83 / 0 / $cd / $10 );
if vga then setscanlines(2);
end;
BEGIN
detEGA;
END.